package vn.kiemviec.app.utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnManagerParams;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;

import android.util.Log;


public final class HttpUtils {

	private final static String TAG = HttpUtils.class.getSimpleName();

	private static HttpParams defaultHttpParams = new BasicHttpParams();
	private static SchemeRegistry trustedSchemeRegistry = TrustedRegistryFactory.newTrustedSchemeRegistry();
	private static SchemeRegistry defaultSchemeRegistry = new SchemeRegistry();

	private static String UserAgent = "CommonClient/1.0";
	private static Map<String, String> Headers = new HashMap<String, String>();
	private static Credentials credentials;

	static {
		
		defaultSchemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
		defaultSchemeRegistry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));

		HttpProtocolParams.setContentCharset(defaultHttpParams, HTTP.DEFAULT_CONTENT_CHARSET);
		HttpConnectionParams.setConnectionTimeout(defaultHttpParams, 60000);
		HttpConnectionParams.setSoTimeout(defaultHttpParams, 60000);
		HttpConnectionParams.setSocketBufferSize(defaultHttpParams, 1024 * 8);// 8KB
		ConnManagerParams.setTimeout(defaultHttpParams, 30000);
	}

	
	private HttpUtils() {
		
	}

	
	public static void configureHttpClient(String userAgent, NameValuePair... headers) {
		if (!StringUtils.isEmpty(userAgent)) {
			UserAgent = userAgent;
		}
		if (!CollectionUtils.isEmpty(headers)) {
			Headers.clear();
			for (NameValuePair pair : headers) {
				Headers.put(pair.getName(), pair.getValue());
			}
		}
	}

	
	public static void configureCredentials(Credentials credentials) {
		HttpUtils.credentials = credentials;
	}

	
	public static String urlEncode(String value) throws UnsupportedEncodingException {
		if (null == value) {
			return null;
		} else {
			return URLEncoder.encode(value, StringUtils.UTF_8);						
		}
	}

	
	public static String urlDecode(String value) throws UnsupportedEncodingException {
		if (null == value) {
			return null;
		} else {
			return URLDecoder.decode(value, StringUtils.UTF_8);
		}
	}

	
	public static String buildQueryString(String url, List<NameValuePair> params) throws IOException {
		StringBuilder sb = new StringBuilder();
		for (NameValuePair param : params) {
			sb.append(urlEncode(param.getName()));
			sb.append("=");
			sb.append(urlEncode(param.getValue()));
			sb.append("&");
		}

		return url + "?" + sb.substring(0, sb.length() - 1);
	}

	
	public static HttpClient newClient() {
		HttpParams params = ((BasicHttpParams) defaultHttpParams).copy();
		ClientConnectionManager connectionManager = new ThreadSafeClientConnManager(params, defaultSchemeRegistry);
		return new DefaultHttpClient(connectionManager, params);
	}

	
	
	public static HttpClient newAllTrustClient() {
		HttpParams params = ((BasicHttpParams) defaultHttpParams).copy();
		ClientConnectionManager connectionManager = new ThreadSafeClientConnManager(params, trustedSchemeRegistry);
		return new DefaultHttpClient(connectionManager, params);
	}

	
	
	private static HttpResponse execute(HttpUriRequest request) throws IOException, HttpException {
		ClientConnectionManager connectionManager = new ThreadSafeClientConnManager(defaultHttpParams, defaultSchemeRegistry);
		HttpClient client = new DefaultHttpClient(connectionManager, defaultHttpParams);

		return execute(client, request);
	}


	private static HttpResponse execute(HttpClient client, HttpUriRequest request) throws IOException, HttpException {
		HttpProtocolParams.setUserAgent(defaultHttpParams, UserAgent);
		for (Map.Entry<String, String> header : Headers.entrySet()) {
			request.addHeader(header.getKey(), header.getValue());
		}

		if (null != credentials) {
			((DefaultHttpClient) client).getCredentialsProvider().setCredentials(AuthScope.ANY, credentials);
		}

		return retrieveResponse(request, client.execute(request));
	}

	public static HttpResponse retrieveResponse(HttpUriRequest request, HttpResponse response) throws IOException {
		StatusLine status = response.getStatusLine();

		if (status.getStatusCode() != HttpURLConnection.HTTP_OK) {
			String message = String.format("HTTP Error (%s:%s => %d:%s)",//
				request.getMethod(), //
				request.getURI().toString(), //
				status.getStatusCode(),//
				status.getReasonPhrase());


			throw new HttpException(status.getStatusCode(), status.getReasonPhrase(), message);
		}

		return response;
	}

	public static byte[] getAsBytes(String url) throws IOException, HttpException {
		return StreamUtils.toByteArray(getAsStream(url));
	}

	public static InputStream getAsStream(String url) throws IOException, HttpException {
		return get(url).getEntity().getContent();
	}

	public static InputStream getAsStream(String url, List<NameValuePair> params) throws IOException, HttpException {
		String str = buildQueryString(url, params);
		Log.i("TrungTT",""+str);
		
		//urlDecode("");
		return getAsStream(buildQueryString(url, params));
	}

	public static HttpResponse get(String url) throws IOException, HttpException {

		HttpGet get = new HttpGet(url);
		HttpResponse response = execute(get);

		return response;
	}
	public static HttpResponse get(HttpClient client, String url) throws IOException, HttpException {

		HttpGet request = new HttpGet(url);

		return execute(client, request);
	}

	public static InputStream postAsStream(String url, List<NameValuePair> params) throws IOException {

		HttpPost post = new HttpPost(url);
		post.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
		HttpResponse response = execute(post);

		return response.getEntity().getContent();
	}


	public static void getAsFile(String url, String filePath) throws IOException {
		InputStream in = getAsStream(url);

		try {
			IOUtils.writeFile(in, filePath);
		} finally {
			IOUtils.close(in);
		}
	}
}
